/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package rlpw.swing;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Comparator;
import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.event.EventListenerList;

/**
 *
 * @author weinpau
 */
public class JORadioGroup<T> extends JPanel implements View<T> {

    private Model<T> model;
    private SelectModel<T> selected;
    private Filter<T> filter;
    private Comparator<T> sorter;
    private EventListenerList listeners = new EventListenerList();

    public JORadioGroup() {
        this(new DefaultModel<T>(), null);
    }

    public JORadioGroup(String title) {
        this(new DefaultModel<T>(), title);
    }

    public JORadioGroup(Model<T> model) {
        this(model, null);
    }

    public JORadioGroup(Model<T> model, String title) {
        if (title != null) {
            setBorder(BorderFactory.createTitledBorder(title));
        }

        setFilter(null);
        model.addView(this);
        selected = new DefaultSelectModel<T>(this);
        selected.setMode(SelectModel.SINGLE);
        setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
        updateView();

    }

    public void updateView() {
        removeAll();

        for (final T item : new FilteredList<T>(this)) {
            final JRadioButton cb = new JRadioButton(item.toString(), getSelectModel().isSelected(item));
            cb.addActionListener(new ActionListener() {

                public void actionPerformed(ActionEvent e) {
                    getSelectModel().setSelected(item, cb.isSelected());
                    fireActionEvent();
                }
            });
            cb.setFocusPainted(false);
            add(cb);
        }
        revalidate();
        repaint();
    }

    public Model<T> getDataModel() {
        return model;
    }

    public void setDataModel(Model<T> model) {
        this.model = model;
        if (getSelectModel() != null) {
            updateView();
        }
    }

    public CheckModel<T> getCheckModel() {
        return null;
    }

    public SelectModel<T> getSelectModel() {
        return selected;
    }

    public Filter<T> getFilter() {
        return filter;
    }

    public void setFilter(Filter<T> filter) {
        if (filter == null) {
            this.filter = new DefaultFilter<T>();
        } else {
            this.filter = filter;
        }
        if (getSelectModel() != null) {
            updateView();
        }
    }

    public void setSorter(Comparator<T> comp) {
        sorter = comp;
        updateView();
    }

    public Comparator<T> getSorter() {
        return sorter;
    }

    public T getSelectedItem() {
        if (getSelectModel().countSelected() > 0) {
            return getSelectModel().getSelected().get(0);
        } else {
            return null;
        }
    }

    public void setSelectedItem(T item) {
        getSelectModel().setSelected(item, true);
    }

    public void addActionListener(ActionListener l) {
        listeners.add(ActionListener.class, l);
    }

    public void removeActionListener(ActionListener l) {
        listeners.remove(ActionListener.class, l);
    }

    protected synchronized void fireActionEvent() {
        getDataModel().updateViews();
        ActionEvent event = new ActionEvent(this, ActionEvent.ACTION_PERFORMED, "");
        for (ActionListener l : listeners.getListeners(ActionListener.class)) {
            l.actionPerformed(event);
        }
    }
}
